﻿using System;
using System.Collections.ObjectModel;
using System.Linq;

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;

using Rio.Framework.Localisation;
using Rio.Framework.Pages;
using Rio.Framework.Pages.Context;
using Rio.Manager.Application.ViewModel.BaseClass;
using Rio.Manager.Application.ViewModel.Locator;

namespace Rio.Manager.Application.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        #region Fields

        private string _rioManagerTitle;
        private int _selectedTab;
        private ObservableCollection<TabViewModelBase> _viewModelTabItems;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            InitCommands();

            Messenger.Default.Register<NotificationMessage<Tuple<TabViewModelBase, Action<TabViewModelBase>>>>(this, ManageTabsViewModels);
        }

        #endregion Constructors

        #region Properties

        public RelayCommand InitializationCommand
        {
            get;
            set;
        }

        public string RioManagerTitle
        {
            get { return _rioManagerTitle; }
            set
            {
                _rioManagerTitle = value;
                RaisePropertyChanged("RioManagerTitle");
            }
        }

        public int SelectedTab
        {
            get { return _selectedTab; }
            set
            {
                _selectedTab = value;
                RaisePropertyChanged("SelectedTab");
            }
        }

        public ObservableCollection<TabViewModelBase> ViewModelTabItems
        {
            get { return _viewModelTabItems; }
            set
            {
                _viewModelTabItems = value;
                RaisePropertyChanged("ViewModelTabItems");
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Initializations this instance.
        /// </summary>
        public void Initialization()
        {
            InitLabels();
            InitializeFixedTabItems();
            SelectedTab = 0;
        }

        /// <summary>
        /// Adds the tab.
        /// </summary>
        /// <param name="newTab">The new tab.</param>
        /// <param name="actionToProcessBeforeAddTab">The action to process before add tab.</param>
        private void AddTab(TabViewModelBase newTab, Action<TabViewModelBase> actionToProcessBeforeAddTab)
        {
            if (!ViewModelTabItems.Any(p => p.GetType() == newTab.GetType()))
            {
                if (actionToProcessBeforeAddTab != null)
                {
                    actionToProcessBeforeAddTab.Invoke(newTab);
                }

                ViewModelTabItems.Add(newTab);
            }
            else
            {
                MessageBoxChildWindow window = new MessageBoxChildWindow(String.Empty, "Un onglet de ce type est déjà ouvert. Veuillez fermer l'onglet pour en ouvrir un autre.", MessageBoxButtons.Ok, MessageBoxIcon.Information);
                window.ShowDialog();
            }

            SelectedTab = ViewModelTabItems.IndexOf(newTab);
        }

        /// <summary>
        /// Closes the tab.
        /// </summary>
        /// <param name="tabToClose">The e.</param>
        private void CloseTab(TabViewModelBase tabToClose)
        {
            if (ViewModelTabItems.Contains(tabToClose))
            {
                ViewModelTabItems.Remove(tabToClose);

                // Call Clear method of current ViewModel
                Type viewModelType = tabToClose.GetType();

                var clearMethod = typeof(ViewModelLocator).GetMethod(String.Format("Clear{0}", viewModelType.Name.Replace("ViewModel", String.Empty)), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
                clearMethod.Invoke(null, null);
            }
        }

        /// <summary>
        /// Inits the commands.
        /// </summary>
        private void InitCommands()
        {
            InitializationCommand = new RelayCommand(Initialization);
        }

        /// <summary>
        /// Initializes the fixed tab items.
        /// </summary>
        private void InitializeFixedTabItems()
        {
            ViewModelTabItems = new ObservableCollection<TabViewModelBase>();

            AddTab(ViewModelLocator.DashboardTabStatic, null);
            AddTab(ViewModelLocator.AdministrationTabStatic, null);
            AddTab(ViewModelLocator.FolderTypeAdministrationTabStatic, null);

            //if (!String.IsNullOrWhiteSpace(GlobalWebContext.RioAppSettings["Administration_CustomerTab_XAP_Path"]))
            //    AddTab(ViewModelLocator.CustomerTabStatic, null);
        }

        /// <summary>
        /// Inits the label.
        /// </summary>
        private void InitLabels()
        {
            RioManagerTitle = Resx.GetLabel(ResxRioManager.RIO_WEB_MANAGER);

            ViewModelLocator.FolderTypeAdministrationTabStatic.TabTitle = Resx.GetLabel(ResxRioManager.FOLDER_TYPE_ADMINISTRATION_TAB);
            ViewModelLocator.DashboardTabStatic.TabTitle = Resx.GetLabel(ResxRioManager.DASHBOARD_TAB);
            ViewModelLocator.AdministrationTabStatic.TabTitle = Resx.GetLabel(ResxRioManager.ADMINISTRATION_TAB);

            //if (!String.IsNullOrWhiteSpace(GlobalWebContext.RioAppSettings["Administration_CustomerTab_XAP_Path"]))
            //    ViewModelLocator.CustomerTabStatic.TabTitle =
            //        GlobalWebContext.RioAppSettings["Administration_CustomerTab_Title"];
        }

        /// <summary>
        /// Manages the view models.
        /// </summary>
        /// <param name="e">The e.</param>
        private void ManageTabsViewModels(NotificationMessage<Tuple<TabViewModelBase, Action<TabViewModelBase>>> e)
        {
            switch (e.Notification.ToLowerInvariant())
            {
                case "add":
                    AddTab(e.Content.Item1, e.Content.Item2);
                    break;
                case "close":
                    CloseTab(e.Content.Item1);
                    break;
                default:
                    break;
            }
        }

        #endregion Methods
    }
}